<template>
  <div class="FirstPerson">
    <canvas id="canvas" />
  </div>
</template>

<script lang="ts" setup>
import {
  AnimationMixer,
  Clock,
  Color,
  Scene,
  Group,
  Object3D,
  Box3,
} from "three";
import { onMounted } from "vue";
import InitScene from "../utils/InitScene";
import { defaultLoaderModel } from "../utils/loaderModel";
import { DefaultSelectOperate } from "../utils/SelectOperate";
import { FirstPersonControls } from "Three/examples/jsm/controls/FirstPersonControls";

let canvas: HTMLCanvasElement | null;
let scene: Scene;
const defaultInitScene = new InitScene();
const clock = new Clock();
let animationMixer: AnimationMixer;
let sceneGroup: Group = new Group();
let firstPersonControl: FirstPersonControls;
onMounted(() => {
  canvas = document.querySelector("#canvas");
  if (!canvas) return;
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  defaultInitScene.init(canvas);
  defaultInitScene.scene.background = new Color("#5de9ff");
  document
    .querySelector(".wrapper")
    ?.appendChild(defaultInitScene.renderer.domElement);
  scene = defaultInitScene.scene;
  scene.background = new Color("#D6D7D8");
  defaultLoaderModel
    .load("city_grid/scene.gltf")
    .addEventListener("loaded", (e) => {
      let data = e.data;
      let {
        data: { scene },
      } = data;
      sceneGroup.add(setSceneCenter(scene));
      defaultInitScene.scene.add(sceneGroup);
    });
  defaultInitScene.addEventListener("animate", () => {
    animationMixer && animationMixer.update(clock.getDelta());
    const delta = clock.getDelta(); //获取自上次调用的时间差
    if (firstPersonControl && firstPersonControl.enabled) {
      firstPersonControl.update(delta);
    }
  });
  defaultInitScene.renderer.domElement.addEventListener("mousemove", (e) => {
    DefaultSelectOperate.handleMouse(
      e.clientX,
      e.clientY,
      defaultInitScene.camera,
      defaultInitScene.scene
    );
  });
  createFirstPersonControls();
  defaultInitScene.renderer.domElement.addEventListener("dblclick", (e) => {
    firstPersonControl.enabled = true;
  });
  document.body.addEventListener("mouseout", (e) => {
    firstPersonControl.enabled = false;
  });
});

function setSceneCenter(scene: Object3D): Object3D {
  let box = new Box3().setFromObject(scene); // 获取模型的包围盒
  let mdlen = box.max.x - box.min.x; // 模型长度
  let mdwid = box.max.z - box.min.z; // 模型宽度
  let mdhei = box.max.y - box.min.y; // 模型高度
  let x1 = box.min.x + mdlen / 2; // 模型中心点坐标X
  let y1 = box.min.y + mdhei / 2; // 模型中心点坐标Y
  let z1 = box.min.z + mdwid / 2; // 模型中心点坐标Z
  scene.position.set(-x1, -y1, -z1); // 将模型进行偏移
  return scene;
}

function createFirstPersonControls() {
  firstPersonControl = new FirstPersonControls(
    defaultInitScene.camera,
    defaultInitScene.renderer.domElement
  );
  firstPersonControl.enabled = false;
  firstPersonControl.lookSpeed = 0.1; //鼠标移动查看的速度
  firstPersonControl.movementSpeed = 10; //相机移动速度
  firstPersonControl.constrainVertical = true; //约束垂直
  firstPersonControl.verticalMin = 1.0;
  firstPersonControl.verticalMax = 2.0;
}
</script>
